package com.htthorizon.aop.aspect;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.htthorizon.aop.annotation.Operate;
import com.htthorizon.common.core.context.SecurityContextHolder;
import com.htthorizon.common.core.web.domain.AjaxResult;
import com.htthorizon.common.security.utils.SecurityUtils;
import com.htthorizon.model.domain.ModelInfo;
import com.htthorizon.model.domain.ModelUse;
import com.htthorizon.model.enums.OperateType;
import com.htthorizon.model.request.ModelSearchReq;
import com.htthorizon.model.service.IModelInfoService;
import com.htthorizon.model.service.IModelMetaService;
import com.htthorizon.model.service.IModelUseService;
import com.htthorizon.system.api.domain.SysDept;
import com.htthorizon.system.api.domain.SysUser;
import com.htthorizon.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author Brilliant
 */
@Aspect
@Component
@Slf4j
public class OperateAspect {

    @Autowired
    private IModelUseService modelUseService;

    @Autowired
    private IModelInfoService modelInfoService;

    @Autowired
    private IModelMetaService modelMetaService;

    @AfterReturning(value = "@annotation(operate)", returning = "rvt")
    public void boAfter(JoinPoint joinPoint, Operate operate,Object rvt){
        String userName = SecurityContextHolder.getUserName();
        Long userId = SecurityContextHolder.getUserId();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getSysUser();
        SysDept dept = sysUser.getDept();

        ModelUse modelUse = new ModelUse();

        if (dept==null){
            modelUse.setCreateDept("长沙");
        }else {
            modelUse.setCreateDept(dept.getDeptName());
        }

        DateTime date = DateUtil.date();
        modelUse.setCreateTime(date);
        modelUse.setCreateBy(userName);
        modelUse.setCreateId(userId);
        if (operate.type().equals(OperateType.QUERY)){
            Object[] args = joinPoint.getArgs();
            ModelSearchReq modelSearchReq=(ModelSearchReq) args[0];
            log.info("modelSearch : {}" , modelSearchReq);
            modelUse.setModelId(modelSearchReq.getModelId());
            ModelInfo modelInfo = modelInfoService.selectModelInfoById(modelSearchReq.getModelId());
            modelUse.setModelName(modelInfo.getModelName());
            OperateType type = operate.type();
            modelUse.setType(type.getValue());
            JSONObject searchData = new JSONObject(modelSearchReq.getSearchJson());
            searchData.remove("pageNum");
            searchData.remove("pageSize");


            Map<String, String> map = new LinkedHashMap<>();
            Set<String> strings = searchData.keySet();
            strings.forEach(key->{
                String znName = modelMetaService.selectModelMetaByEnName(key);
                map.put(znName,searchData.get(key,String.class));
            });

            modelUse.setSearchData(map.toString());

            JSONObject entries = new JSONObject(modelSearchReq.getSearchJson());
            String checkDept = (String)entries.get("std_city_org_nm");
            modelUse.setCheckDept(checkDept);
            Object o = ((AjaxResult) rvt).get("total");

            modelUse.setTotal(o.toString());
            modelUseService.save(modelUse);

        }else {
            Object[] args = joinPoint.getArgs();
            ModelSearchReq modelSearch=(ModelSearchReq) args[0];
            log.info("modelSearch : {}" , modelSearch);
            modelUse.setModelId(modelSearch.getModelId());
            ModelInfo modelInfo = modelInfoService.selectModelInfoById(modelSearch.getModelId());
            modelUse.setModelName(modelInfo.getModelName());
            OperateType type = operate.type();
            modelUse.setType(type.getValue());

            JSONObject entries = new JSONObject(modelSearch.getSearchJson());

            entries.remove("pageNum");
            entries.remove("pageSize");


            Map<String, String> map = new LinkedHashMap<>();
            Set<String> strings = entries.keySet();
            strings.forEach(key->{
                String znName = modelMetaService.selectModelMetaByEnName(key);
                map.put(znName,entries.get(key,String.class));
            });
            modelUse.setSearchData(map.toString());


            String checkDept = (String)entries.get("std_city_org_nm");
            modelUse.setCheckDept(checkDept);
            Object o = ((AjaxResult) rvt).get("total");

            modelUse.setTotal(o.toString());
            modelUseService.save(modelUse);
        }

    }
}
